// EditTrace.vue
<template>
  <div class="editor-container">
    <div class="toolbar">
      <div class="toolbar-items">
        <span class="toolbar-button" @click="undo">撤销</span>
        <span class="toolbar-button" @click="redo">重做</span>
        <span class="toolbar-button" @click="verify">确认</span>
      </div>
      <div class="toolbar-info">
        <span>字数：{{ content.length }}</span>
      </div>
    </div>
    <div class="editor-wrapper">
      <textarea
          class="editor-textarea"
          v-edit-trace:[maxSize]="initialContent"
          @edit-trace="handleEditTrace"
          :style="'height:' + editorHeight + 'px'"
          v-model="content"
      ></textarea>
      <div class="editor-show" v-html="diffHtml"></div>
    </div>
  </div>
</template>

<script>
import {computed, ref, watch} from 'vue';

export default {
  props: {
    initialContent: {
      type: String,
      default: ''
    },
    editorHeight: {
      type: Number,
      default: 300
    },
    maxSize: {
      type: Number,
      default: 300
    }
  },
  setup(props, {emit}) {
    const history = ref([{diff: {added: [], removed: []}, value: props.initialContent}]);
    const currentIndex = ref(0);
    const diff = ref({added: [], removed: []});
    const content = ref(props.initialContent);

    const diffHtml = computed(() => {
      let result = content.value.split('');

      console.log(result)

      // 处理新增内容
      diff.value.added.forEach(addedChar => {
        result.splice(addedChar.index, addedChar.char.length, `<span style="color: blue;">${addedChar.char}</span>`);
      });

      // 处理删除内容
      diff.value.removed.forEach(removedChar => {
        result.splice(removedChar.index, 0, `<span style="color: red; text-decoration: line-through;">${removedChar.char}</span>`);
      });

      return result.join('');
    });

    const handleEditTrace = (event) => {
      if (content.value.length < props.maxSize) {
        const {diff: diffValue, newValue} = event.detail;
        if (currentIndex.value < history.value.length - 1) {
          history.value = history.value.slice(0, currentIndex.value + 1);
        }
        history.value.push({diff: diffValue, value: newValue});
        currentIndex.value++;
        diff.value = diffValue;
        emit('update:initialContent', newValue);
      }
    };

    const undo = () => {
      if (currentIndex.value > 0) {
        currentIndex.value--;
        const {value} = history.value[currentIndex.value];
        content.value = value;
        diff.value = history.value[currentIndex.value].diff;
        emit('update:initialContent', value);
      }
    };

    const redo = () => {
      if (currentIndex.value < history.value.length - 1) {
        currentIndex.value++;
        const {value} = history.value[currentIndex.value];
        content.value = value;
        diff.value = history.value[currentIndex.value].diff;
        emit('update:initialContent', value);
      }
    };

    const verify = () => {
      history.value = [{diff: {added: [], removed: []}, value: content.value}];
      currentIndex.value = 0;
      diff.value = {added: [], removed: []};
    }

    const getFinalValue = () => {
      return content.value;
    };

    const getHtmlValue = () => {
      return diffHtml.value;
    };

    const getParsedValue = () => {
      return JSON.stringify({
        content: content.value,
        added: diff.value.added,
        removed: diff.value.removed
      });
    };

    watch(
        () => props.initialContent,
        (newValue) => {
          content.value = newValue;
        }
    );

    return {
      content,
      diffHtml,
      handleEditTrace,
      undo,
      redo,
      verify,
      getFinalValue,
      getHtmlValue,
      getParsedValue
    };
  }
};
</script>

<style scoped>
.editor-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  background-color: #cccccc;
  border: 1px solid #000000;
  border-radius: 4px 4px 0 0;
}

.toolbar .toolbar-items {
  display: flex;
  justify-content: flex-start;
}

.toolbar-button {
  padding: 8px;
  color: #000;
  cursor: pointer;
  border-right: 1px solid;
}

.toolbar .toolbar-info {
  margin-right: 8px;
}

.editor-wrapper {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-height: 92%;
}

.editor-textarea {
  width: auto;
  padding: 0;
  font-size: 14px;
  border: 1px solid;
  resize: vertical;
}

.editor-textarea:focus {
  outline: 0;
}

.editor-show {
  overflow-y: auto;
  flex-grow: 1;
  padding: 8px;
  word-break: break-all;
}
</style>